package com.igoal.entity;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import org.compass.annotations.SearchableId;
import org.compass.annotations.SearchableProperty;
import org.hibernate.annotations.Type;

@Entity
@Table(name="user_goal_phase")
public class UserGoalPhase extends BaseObject implements Audit, ItemOwner {
	
	private static final long serialVersionUID = -6384287254531698440L;
	
	private Long id;
	private String phaseName;
	private Integer index;
	private Integer percentMeasure;
	private Integer taskCount;
	private Integer remainingTaks;
	private Boolean finished;
	private Boolean failed;
	private Date deadLine;
	private Date createDate;
	private Date updateDate;
	private DataStatus status;
	
	private UserGoal userGoal;
	
	private Set<UserGoalTask> taskList = new HashSet<UserGoalTask>(0);
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@SearchableId
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	@ManyToOne
	@JoinColumns({
		@JoinColumn(name="user_id", referencedColumnName="user_id"),
		@JoinColumn(name="goal_id", referencedColumnName="goal_id")
	})
	public UserGoal getUserGoal() {
		return userGoal;
	}

	public void setUserGoal(UserGoal userGoal) {
		this.userGoal = userGoal;
	}
	
	@Column(name="phase_index", nullable=false)
	public Integer getIndex() {
		return index;
	}

	public void setIndex(Integer index) {
		this.index = index;
	}	
	
	@Column(name="percent_measure", nullable=true)
	public Integer getPercentMeasure() {
		return percentMeasure;
	}

	public void setPercentMeasure(Integer percentMeasure) {
		this.percentMeasure = percentMeasure;
	}

	@Column(name="dead_line", nullable=true)
	public Date getDeadLine() {
		return deadLine;
	}

	public void setDeadLine(Date deadLine) {
		this.deadLine = deadLine;
	}
	
	@Column(name="finished", nullable=false)
	@Type(type = "yes_no")
	public Boolean getFinished() {
		return finished;
	}

	public void setFinished(Boolean finished) {
		this.finished = finished;
	}

	@Temporal(TemporalType.TIMESTAMP)
	@Column(nullable=false, name="cdate")
	public Date getCreateDate() {
		return createDate;
	}

	@Enumerated(EnumType.STRING)
	@Column(nullable=false, name="status")
	@SearchableProperty
	public DataStatus getStatus() {
		return status;
	}

	@Temporal(TemporalType.TIMESTAMP)
	@Column(nullable=false, name="mdate")
	public Date getUpdateDate() {
		return updateDate;
	}

	public void setCreateDate(Date date) {
		this.createDate = date;
	}

	public void setStatus(DataStatus dataStatus) {
		this.status = dataStatus;
	}

	public void setUpdateDate(Date date) {
		this.updateDate = date;
	}
	
	@Column(name="phase_name", nullable=false)
	public String getPhaseName() {
		return phaseName;
	}

	public void setPhaseName(String phaseName) {
		this.phaseName = phaseName;
	}

	@Column(name="num_tasks", nullable=false)
	public Integer getTaskCount() {
		return taskCount;
	}

	public void setTaskCount(Integer taskCount) {
		this.taskCount = taskCount;
	}

	@Column(name="remaining_tasks", nullable=false)
	public Integer getRemainingTaks() {
		return remainingTaks;
	}

	public void setRemainingTaks(Integer remainingTaks) {
		this.remainingTaks = remainingTaks;
	}

	@Column(name="failed", nullable=false)
	@Type(type = "yes_no")
	public Boolean getFailed() {
		return failed;
	}

	public void setFailed(Boolean failed) {
		this.failed = failed;
	}

	@OneToMany(fetch=FetchType.LAZY, mappedBy="userGoalPhase")	
	public Set<UserGoalTask> getTaskList() {
		return taskList;
	}

	public void setTaskList(Set<UserGoalTask> taskList) {
		this.taskList = taskList;
	}

	@Transient
	public User getUser(){
		return userGoal.getUser();
	}
	
	@Transient
	public Goal getGoal(){
		return userGoal.getGoal();
	}
	
	@Override
	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append(getUser().getUsername()).append(" defined phase ").append(phaseName).append(" for goal ").append(getGoal().getTitle());
		return sb.toString();
	}

	@Override
	public boolean equals(Object o) {
		if(o != null && o instanceof UserGoalPhase){
			UserGoalPhase that = (UserGoalPhase) o;
			return id.equals(that.id) && phaseName.equals(that.equals(phaseName));
		}
		
		return false;
	}

	@Override
	public int hashCode() {
		return id.hashCode();
	}

	@Transient
	public User getOwner() {
		return userGoal.getUser();
	}

}
